Skip to content

Enable --pretty by default for better error messages#20768

Open
veeceey wants to merge 6 commits intopython:masterfrom
veeceey:feat/issue-19108-enable-pretty-by-default
Open

Enable --pretty by default for better error messages#20768
veeceey wants to merge 6 commits intopython:masterfrom
veeceey:feat/issue-19108-enable-pretty-by-default

Conversation

@veeceey
Copy link

@veeceey veeceey commented Feb 8, 2026

Summary

This PR enables the --pretty flag by default to provide visually nicer output in error messages. The --pretty option shows error lines with highlighting, uses soft word wrap, and displays source code snippets.

Changes

  • Changed self.pretty = False to self.pretty = True in mypy/options.py
  • Changed default=False to default=True for the --pretty flag in mypy/main.py
  • Updated documentation in docs/source/command_line.rst to reflect the new default and mention --no-pretty

Example Output

With --pretty enabled (new default):

foo.py:13: error: List item 0 has incompatible type "str"; expected "int"  [list-item]
    aa = ["x"]
          ^~~

Without --pretty (using --no-pretty):

foo.py:13: error: List item 0 has incompatible type "str"; expected "int"  [list-item]

Rationale

The additional context makes it easier to see what is wrong. For example, there may be multiple possible expressions which can generate the error, and the highlighting makes this obvious.

Fixes #19108

Changed the default value of --pretty from False to True to provide
visually nicer output by default. Users can still disable it with
--no-pretty if they prefer more concise error messages.

Updated defaults in:
- mypy/options.py: Changed self.pretty = False to True
- mypy/main.py: Changed default=False to default=True for --pretty flag
- docs/source/command_line.rst: Added note about default and --no-pretty

Fixes python#19108
@github-actions

This comment has been minimized.

- Use literal markup for --no-pretty in docs to avoid unknown option warning
- Set pretty=False in test infrastructure so existing test expectations
  remain valid when --pretty is not explicitly passed as a flag
@github-actions

This comment has been minimized.

@wyattscarpenter
Copy link
Contributor

The problem is fixing the test errors, which is what makes #19510 so complicated. Maybe you will find an easier way. But it may be quite difficult.

@veeceey
Copy link
Author

veeceey commented Feb 15, 2026

Thanks for the heads-up! Yeah, I can see the test failures piling up. You're right that this is the trickiest part - the output formatting change ripples through a lot of test cases.

I'm working through the failures systematically. It looks like most of them are in test cases that have hardcoded expectations for the old (non-pretty) output format. I'm updating those to match the new pretty output, though it's definitely tedious.

I'll keep chipping away at it and see if I can find any patterns that'll help batch these updates. Let me know if you spot anything I might be missing!

veeceey and others added 2 commits February 14, 2026 23:18
Fix add_invertible_flag to always use store_true for the flag and
store_false for its inverse, regardless of the default value. The
previous logic inverted the actions when default=True, causing
--pretty to disable pretty mode and --no-pretty to enable it.

Update all test harnesses to explicitly disable pretty mode for tests
that don't opt into it, preventing source code snippets from appearing
in test output that expects non-pretty format.
@github-actions

This comment has been minimized.

Restore the original add_invertible_flag logic where the argparse action
depends on the default value. The previous commit incorrectly simplified
this to always use store_true/store_false, which broke all 7 flags with
default=True (--no-namespace-packages, --no-warn-no-return,
--no-implicit-reexport, --no-color-output, --no-error-summary, etc).

The --pretty default is now controlled solely through Options.pretty=True
in options.py, keeping default=False in add_invertible_flag so the flag
semantics work correctly (--pretty -> store_true, --no-pretty -> store_false).

Also fix ruff PIE810 by merging startswith calls into a tuple.
@github-actions

This comment has been minimized.

The previous logic incorrectly appended --no-pretty after -- for all
dmypy commands (like dmypy check), which caused --no-pretty to be
treated as a filename. It also appended "-- --no-pretty" to dmypy run
commands without --, which argparse rejected.

Fix by:
1. Only injecting --no-pretty for dmypy run/start (not check/recheck)
2. For dmypy run/start without --, properly parse out dmypy-specific
   flags and reconstruct the command with -- separator so --no-pretty
   goes into the mypy flags portion.
@github-actions
Copy link
Contributor

According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enable --pretty by default

2 participants